// Copyright @ ChenChao


#include "Characters/WarriorHeroCharacter.h"
#include "Components/CapsuleComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "EnhancedInputSubsystems.h"
#include "DataAssets/Input/WarriorDataAssetInputConfig.h"
#include "Components/Input/WarriorInputComponent.h"

#include "WarriorDebugHelper.h"
#include "WarriorGameplayTags.h"
#include "AbilitySystem/WarriorAbilitySystemComponent.h"
#include "AbilitySystem/WarriorAttributeSet.h"
#include "DataAssets/StartUp/DataAsset_StartUpDataBase.h"


/*构造函数，初始化属性*/
AWarriorHeroCharacter::AWarriorHeroCharacter()
{
	/*胶囊体组件*/
	GetCapsuleComponent()->InitCapsuleSize(42.f, 92.f);		//初始化胶囊体半径、半高
	bUseControllerRotationPitch = false;	//是否使用控制器的旋转俯仰
	bUseControllerRotationYaw = false;		//是否使用控制器的旋转偏移
	bUseControllerRotationRoll = false;		//是否使用控制器的旋转翻滚

	/*弹簧臂组件*/
	CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
	CameraBoom->SetupAttachment(GetRootComponent());		//设置父级（根组件）
	CameraBoom->TargetArmLength = 200.f;		//设置臂长
	CameraBoom->SocketOffset = FVector(0.f, 55.f, 65.f);		//插槽偏移
	CameraBoom->bUsePawnControlRotation = true;		//使用棋子控制旋转

	/*相机组件*/
	FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
	FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName);		//设置父级（弹簧臂插槽名称）
	FollowCamera->bUsePawnControlRotation = false;

	/*角色移动组件*/
	GetCharacterMovement()->bOrientRotationToMovement = true;		//保持旋转到位移方向
	GetCharacterMovement()->RotationRate = FRotator(0.f, 500.f, 0.f);		//旋转速度（转身速度）
	GetCharacterMovement()->MaxWalkSpeed = 400.f;		//最大位移速度
	GetCharacterMovement()->BrakingDecelerationWalking = 200.f;		//行走加速度
	
}

//当Controller（玩家或AI）获得该Pawn控制权时触发
void AWarriorHeroCharacter::PossessedBy(AController* NewController)
{
	Super::PossessedBy(NewController);

	if (CharacterStartUpData.IsNull()) return;
	UDataAsset_StartUpDataBase* LoadedData = CharacterStartUpData.LoadSynchronous();
	if (LoadedData == nullptr) return;
	LoadedData->GiveToAbilitySystemComponent(WarriorAbilitySystemComponent);
}

//设置玩家输入组件
void AWarriorHeroCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

	checkf(DataAssetInputConfig,TEXT("DataAssetInputConfig 指针为空！"));
	// 获取本地玩家
	class ULocalPlayer* LocalPlayer = GetController<APlayerController>()->GetLocalPlayer();
	check(LocalPlayer);
	// 获取增强输入本地玩家子系统
	UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(LocalPlayer);
	check(Subsystem);
	//添加映射上下文
	Subsystem->AddMappingContext(DataAssetInputConfig->DefaultMappingContext, 0);

	//获取战士输入组件
	UWarriorInputComponent* WarriorInputComponent = CastChecked<UWarriorInputComponent>(PlayerInputComponent);
	// 绑定回调函数
	WarriorInputComponent->BindNativeInputAction(DataAssetInputConfig, WarriorGameplayTags::InputTag_Move, ETriggerEvent::Triggered, this, &AWarriorHeroCharacter::Input_Move);
	WarriorInputComponent->BindNativeInputAction(DataAssetInputConfig, WarriorGameplayTags::InputTag_Look, ETriggerEvent::Triggered, this, &AWarriorHeroCharacter::Input_Look);
}

void AWarriorHeroCharacter::BeginPlay()
{
	Super::BeginPlay();

	
}

//回调函数: 移动输入
void AWarriorHeroCharacter::Input_Move(const FInputActionValue& InputActionValue)
{
	//获取移动二维向量
	const FVector2D MovementVector = InputActionValue.Get<FVector2D>();
	// 获取移动旋转
	const FRotator MovementRotator(0.f, GetControlRotation().Yaw, 0.0f);
	//设置前进
	if (MovementVector.Y != 0.f)
	{
		//前进方向
		const FVector ForwardDirection = MovementRotator.RotateVector(FVector::ForwardVector);
		//添加移动输入
		AddMovementInput(ForwardDirection, MovementVector.Y);
	}
	//设置向右
	if (MovementVector.X != 0.f)
	{
		//向右方向
		const FVector RightDirection = MovementRotator.RotateVector(FVector::RightVector);
		AddMovementInput(RightDirection, MovementVector.X);
	}
	
}

//回调函数: 视角输入
void AWarriorHeroCharacter::Input_Look(const FInputActionValue& InputActionValue)
{
	//获取鼠标轴二维向量
	const FVector2D LookAxisVector = InputActionValue.Get<FVector2D>();
	//左右看
	if (LookAxisVector.X != 0.f)
	{
		AddControllerYawInput(LookAxisVector.X);
	}
	// 上下看
	if (LookAxisVector.Y != 0.f)
	{
		AddControllerPitchInput(LookAxisVector.Y);
	}
}


